package br.com.conciliador.consulta.negocio;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Order;

import br.com.conciliador.consulta.vo.ConsultaDuplicidadeVo;
import br.com.conciliador.consulta.vo.ResultadoConsultaDuplicidadeVo;
import br.com.conciliador.util.hibernate.business.HibernateUtil;
import br.com.conciliador.util.hibernate.business.R2HbNgc;
import br.com.r2.exception.R2Exception;
import br.com.r2.util.hibernate.business.NegocioThrow;
import br.com.r2.util.hibernate.business.RestritorHb;
import br.com.r2.util.tipodado.InteiroLongo;

public class ConsultaDuplicidadeNgc extends R2HbNgc<ConsultaDuplicidadeVo>
{

   private Map filtroPropriedade = new HashMap();

   private Map restritores = new HashMap();

   private static ConsultaDuplicidadeNgc instancia = null;

   private ConsultaDuplicidadeNgc()
   {
      init(restritores, filtroPropriedade, ConsultaDuplicidadeVo.class);
      addFiltro("dataVenda", RestritorHb.RESTRITOR_DATA_INICIAL,"filtro.dataVendaInicial");
      addFiltro("dataVenda", RestritorHb.RESTRITOR_DATA_FINAL,"filtro.dataVendaFinal");
   }

   public static ConsultaDuplicidadeNgc getInstancia()
   {
      if (instancia == null)
      {
         instancia = new ConsultaDuplicidadeNgc();
      }
      return instancia;
   }

   @Override
   protected Map filtroPropriedade()
   {
      return filtroPropriedade;
   }

   @Override
   protected Criteria montaCriteria(Session sessao, int join)
   {
      Criteria criteria = sessao.createCriteria(ConsultaDuplicidadeVo.class);
      return criteria;
   }

   @Override
   protected Map restritores()
   {
      return restritores;
   }

   @Override
   protected void setarOrdenacao(Criteria criteria, ConsultaDuplicidadeVo filter, int join)
   {
      criteria.addOrder(Order.asc("numeroCartao"));
      criteria.addOrder(Order.asc("dataVenda"));
      criteria.addOrder(Order.asc("nomeLoja"));
      criteria.addOrder(Order.asc("nomeBandeira"));
      criteria.addOrder(Order.asc("nomeProduto"));
   }
   
   public List<ConsultaDuplicidadeVo> pesquisarResultTransformer(Session session, ConsultaDuplicidadeVo filter, int join) throws Exception
   {
      this.addFiltroValidacao(session, filter);

      Criteria criteria = this.montaCriteria(session, join);

      this.setarOrdenacao(criteria, filter, join);

      this.restringir(criteria, filter);
      
      this.setNumeroMaximoRegistros(session, criteria, filter, join);

      criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
      
      return criteria.list();
   }
   
   public List<ResultadoConsultaDuplicidadeVo> pesquisarPorCartao(ConsultaDuplicidadeVo filter, int join) throws R2Exception
   {
      
      Session sessao = HibernateUtil.getInstancia().getSession();
      sessao.setFlushMode(FlushMode.COMMIT);
      try
      {
         return pesquisarPorCartao(sessao, filter, join);
      }
      catch (Exception e)
      {
         throw NegocioThrow.getInstancia().catchHBConsultaSession(e);
      }
      finally
      {
         sessao.close();
      }
      
   }

   
   private List<ResultadoConsultaDuplicidadeVo> pesquisarPorCartao(Session sessao, ConsultaDuplicidadeVo filter, int join) throws Exception
   {
      List<ResultadoConsultaDuplicidadeVo> retorno = new ArrayList<ResultadoConsultaDuplicidadeVo>();
      
      List<ConsultaDuplicidadeVo> listCartao = this.pesquisar(sessao, filter, join);
      
      if (listCartao != null && listCartao.size() > 0)
      {
         ResultadoConsultaDuplicidadeVo resultadoVo = null;
         Iterator<ConsultaDuplicidadeVo> iterator = listCartao.iterator();
         InteiroLongo aux = new InteiroLongo(0);
         List<ConsultaDuplicidadeVo> lista = new ArrayList<ConsultaDuplicidadeVo>();
         boolean primeiro = true;
         int qtde = 0;
         while (iterator.hasNext())
         {
            ConsultaDuplicidadeVo element = (ConsultaDuplicidadeVo) iterator.next();
            
            if (primeiro)
            {
               aux = element.getNumeroCartao();
               primeiro = false;
            }
            
            if (aux.getValor() != element.getNumeroCartao().getValor())
            {
               resultadoVo = new ResultadoConsultaDuplicidadeVo();
               resultadoVo.setNumeroCartao(aux);
               resultadoVo.setListaVendas(lista);
               
               retorno.add(resultadoVo);

               aux = element.getNumeroCartao();
               lista = new ArrayList<ConsultaDuplicidadeVo>();
               lista.add(element);
               qtde = 1;
            }
            else
            {
               lista.add(element);
               qtde++;
            }
         }
         
         if (qtde > 0)
         {
            resultadoVo = new ResultadoConsultaDuplicidadeVo();
            resultadoVo.setNumeroCartao(aux);
            resultadoVo.setListaVendas(lista);
            
            retorno.add(resultadoVo);
         }
      }
      return retorno;
   }

}
